/**
 * dataHandling
 * @description 数组切割
 * @param { Array } arr 数组
 * @param { Number } number 长度
 * @returns { Array }
 */
export function dataHandling(arr, number) {
	let arrLength = arr.length; // 数组长度
	let num = number; // 每页显示的条数
	let index = 0;
	let newArr = [];
	for (let i = 0; i < arrLength; i++) {
		if (i % num === 0 && i !== 0) { // 可以被 10 整除
			newArr.push(arr.slice(index, i));
			index = i;
		};
		if ((i + 1) === arrLength) {
			newArr.push(arr.slice(index, (i + 1)));
		}
	}
	return newArr;
};

/**
 * @description 价格格式化 
 * @param { String | Number } price 金额
 * @param { Number } number 小数点后几位
 * @returns { Number }
 */
export function priceTofixed(price, number) {
	return (Number(price)).toFixed(number || 2);
}

/**
 * whereKeyValue
 * @description 获取数组中含有指定键的对象
 * @param { Array | Object } arr 数组
 * @param { any } key 键
 * @param { any } value 所要包含的值
 * @returns { Object }
 */
export function whereKeyValue(arr, key, value) {
	// 循环所有键
	for (let v in arr) {
		let element = arr[v];
		// 1.判断是对象或者数组
		if (typeof element == "object") {
			let result = whereKeyValue(element, key, value);
			if (result) return result;
		} else {
			if (v == key) {
				if (element == value) return arr;
			}
		}
	}
}

/**
 * findArrayIndex
 * @description 查找对象数组中某个元素的下标并返回
 * @param { Array } arr 对象数组
 * @param { String } key 要查找的键
 * @param { Object } obj 元对象
 * @returns { Number } 元素的下标 || -1(未找到)
 */
export function findArrayIndex(arr, key, obj) {
	return (arr || []).findIndex((arr) => arr[key] === obj[key]);
}

/**
 * 按id的数字大小升序或者是降序排序
 */
export function compare(property, desc) {
	return function(a, b) {
		let value1 = a[property];
		let value2 = b[property];
		if (desc == true) {
			// 升序排列
			return value1 - value2;
		} else {
			// 降序排列
			return value2 - value1;
		}
	};
}

/**
 * @description 数组去重 
 * @param { Array } arr 对象数组 
 * @param { Boolean } flag 类型 
 * @param { Number } batch 字段 
 * @returns { Array } 
 */
export function removedup(arr,flag=true,batch=null) {
	if(flag){  // 方案一【单数组】：[1,2,3,1,4,5]
		for (let i = 0; i < arr.length; i++) {
			for (let j = i + 1; j < arr.length; j++) {
				if (arr[i] == arr[j]) { //第一个等同于第二个，splice方法删除第二个
					arr.splice(j, 1);
					j--;
				}
			}
		}
		return arr;
	}else{  // 方案二【对象数组】：[{name:'aa',val:1},{name:'bb',val:2}]
		if (!Array.isArray(arr)) return arr; // 判断类型
		if (arr.length == 0) return []; // 判断是否为空
		
		let obj = {};
		let uniqueArr = arr.reduce(function(total, item) {
			obj[item[batch]] ? '' : (obj[item[batch]] = true && total.push(item));
			return total;
		}, []);
		return uniqueArr;
	}
}	

/** 防抖。将多次执行变为最后一次执行
 * @example <button @click="onClick">点击</button>
 *	const onClick = debounce(async ()=>{ 业务代码 },1000,true)
 */
export function debounce(fn, delay, immediate = false) {
	/* 简写版： */
	let timer = null;
	return function() {
		clearTimeout(timer);
		timer = setTimeout(() => {
			fn.apply(this, arguments);
		}, delay)
	}

	/* 立即执行：立即执行。如果在n 秒内重复触发,会执行两次【第一次：立即执行。第二次：等待时间结束执行】 */
	// let timer = null
	// let isInvoke = false
	// return function(...ages) {
	// 	if (timer) clearTimeout(timer)

	// 	// 判断是否需要立即执行
	// 	if (immediate && !isInvoke) {
	// 		fn.apply(this, ages)
	// 		isInvoke = true
	// 	} else {
	// 		// 延迟执行
	// 		timer = setTimeout(() => {
	// 			// 外部传入的真正要执行的函数
	// 			fn.apply(this, ages)
	// 			isInvoke = false
	// 		}, delay)
	// 	}
	// }
}

/** 节流。将多次执行变成每隔一段时间执行
 * @example <button @click="onClick">点击</button>
 *	const onClick = throttle(async ()=>{ 业务代码 },1000)
 */
export function throttle(fn, delay) {
	/* 定时器版本一 */
	// let timer;
	// return function() {
	// 	if (timer) return;
	// 	timer = setTimeout(() => {
	// 		console.log('节流');
	// 		fn.apply(this, arguments);
	// 		timer = null
	// 	}, delay)
	// }

	/* 定时器版本二 */
	let valid = true;
	return function() {
		if (valid) { //如果阀门已经打开，就继续往下
			setTimeout(() => {
				fn.apply(this, arguments); //定时器结束后执行
				valid = true; //执行完成后打开阀门
			}, delay)
			valid = false; //关闭阀门
		}
	}

	/* 时间戳版本 */
	// let lastTime = 0;
	// return function() {
	// 	const currentTime = Date.now();
	// 	if (currentTime - lastTime > delay) {
	// 		fn.apply(this, arguments);
	// 		lastTime = currentTime
	// 	}
	// }
}


